package sfin.service;

import static org.apache.commons.lang.StringUtils.isBlank;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.ResourceBundle;

import sfin.swt.exception.StatizoException;
import sfin.swt.util.FormatterUtil;
import br.com.statizo.financeiro.core.repository.impl.CategoriaRepository;
import br.com.statizo.financeiro.domain.entity.impl.Categoria;
import br.com.statizo.financeiro.domain.enums.GrupoLancamento;

public class CategoriaService extends AbstractService{

	private List<Categoria> categorias;
	private CategoriaRepository categoriaRepository;
	
	public CategoriaService(ResourceBundle bundle, FormatterUtil formatterUtil, CategoriaRepository categoriaRepository) {
		super(bundle, formatterUtil);
		this.categoriaRepository = categoriaRepository;
		categorias = categoriaRepository.getList();
		sort();
	}

	public String[] getAllNames(){
		String[] names = new String[categorias.size()];
		for(int i = 0; i<categorias.size(); i++){
			names[i] = categorias.get(i).getNome();
		}
		return names;
	}

	public int indexOf(Categoria categoria){
		return categorias.indexOf(categoria);
	}

	public void sort(){
		Comparator<Categoria> comparator = (c1,c2) -> c1.getNome().compareTo(c2.getNome());
		categorias.sort(comparator);
	}

	public int add(int index,String nome, int grupoIndex) throws StatizoException{
		
		System.out.println("SAVING CATEG: " + index + " " + nome + " " + grupoIndex );
		
		List<String> errors = new ArrayList<String>();

		if(isBlank(nome))
			errors.add(bundle.getString("category.edit.validation.required.name"));

		if(grupoIndex < 0 || grupoIndex > GrupoLancamento.values().length - 1)
			errors.add(bundle.getString("category.edit.validation.required.kind"));			

		if(errors.isEmpty()){
			Categoria categoria = index >= 0 ? categorias.get(index) : new Categoria();
			categoria.setNome(nome);
			categoria.setGrupo(GrupoLancamento.values()[grupoIndex]);

			try{
				
				categoriaRepository.entityManagerRefresh();
				categoriaRepository.beginTransaction();
				categoria = categoriaRepository.merge(categoria);
				categoriaRepository.commit();

				if(!this.categorias.contains(categoria))
					this.categorias.add(categoria);
				sort();
				notifyListeners();
				
			}catch(Exception e){
				errors.add(e.getMessage());
				throw new StatizoException(errors);
			}
			
			return indexOf(categoria);
		}else{
			throw new StatizoException(errors);
		}

	}

	public void del(int selectedIndex) throws StatizoException{
		List<String> errors = new ArrayList<String>();
		Categoria categoria = categorias.get(selectedIndex);
		try{
			categoriaRepository.entityManagerRefresh();
			categoriaRepository.beginTransaction();
			categoria = categoriaRepository.merge(categoria);
			categoriaRepository.remove(categoria);
			categoriaRepository.commit();
			
			categorias.remove(selectedIndex);
			notifyListeners();
		}catch(Exception e){
			errors.add(e.getMessage());
			throw new StatizoException(errors);
		}
	}

	public Categoria getAt(int index){
		return categorias.get(index);
	}

	public String[][] getCategorias(){
		String[][] data = new String[categorias.size()][2];
		for(int i = 0; i<categorias.size(); i++){
			Categoria categ = categorias.get(i);
			data[i][0] = categ.getNome();
			data[i][1] = categ.getGrupo().getNome();
		}
		return data;
	}

	public int count() {
		return categorias.size();
	}

}
